import _ from 'lodash';

function rand(options) {
    options = _.defaults(options, { max: 10, min: 1 });
    return parseInt(Math.random() * (options.max - options.min) + options.min);
}

const generators = {
    '+': (options) => {
        let r1 = rand(options);
        let r2 = rand(options);
        return `${r1} + ${r2} = `;
    },
    '-': (options) => {
        let r1 = rand(options);
        let r2 = rand(options);
        const large = Math.max(r1, r2);
        const small = Math.min(r1, r2);
        return `${large} - ${small} = `;
    },
    '++--': (options) => {
        let r1 = rand(options);
        let r2 = rand(options);
        let r3 = rand(options);

        // generate a formulation with random + or - to make sure the final result is positive
        let formulation = '';
        let result = -1;
        const operations = ['+', '-'];
        do {
            const op1 = operations[Math.floor(Math.random() * operations.length)];
            const op2 = operations[Math.floor(Math.random() * operations.length)];

            formulation = `${r1} ${op1} ${r2} ${op2} ${r3}`;
            let result1 = eval(formulation);
            let result2 = eval(`${r1} ${op1} ${r2}`);

            if (result1 >= 0 && result2 >= 0) {
                result = result1;
            }
        } while (result < 0);
        return formulation;
    },
    '*': (options) => {
        options = _.defaults(options, { max: 99, min: 11 });
        let r1 = rand(options);

        let r2 = rand(options);
        return `${r1} × ${r2} = `;
    },
    '/': (options) => {
        options = _.defaults(options, { max: 9, min: 1 });
        let r1 = rand(options);
        let r2 = rand({ max: 9, min: 2 });
        const r = r1 * r2;
        return `${r} ÷ ${r2} = `;
    },
};

function generateOne(mode, options) {
    const generator = generators[mode];
    if (!generator) {
        console.error('unsupported mode', mode);
    }

    return generator(options);
}

function generate(options) {
    options = _.defaults(options, {
        count: 60,
        patterns: ['-', '+', '*', '/'],
        patternOptions: {
            '+': {
                max: 10,
                min: 0,
            },
            '-': {
                max: 10,
                min: 0,
            },
            '*': {
                max: 99,
                min: 2,
            },
            '/': {
                max: 999,
                min: 11,
            },
        },
    });

    let questions = [];
    for (let i = 0; i < options.count; i++) {
        const pattern = options.patterns[i % options.patterns.length];
        questions.push(generateOne(pattern, options.patternOptions[pattern]));
    }

    questions = _.shuffle(questions);
    return questions;
}

export default generate;
